﻿using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.IE;
using OpenQA.Selenium.Support.Events;
using Selenium.Config;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;

namespace Selenium.Driver
{
    public class WebDriverManager
    {
        private static WebDriverManager _instance;

        protected IWebDriver _webDriver;
        protected EventFiringWebDriver _eventFiringWebDriver;

        public static WebDriverManager Instance
        {
            get
            {
                if (_instance == null)
                {
                    _instance = new WebDriverManager();
                }
                return _instance;
            }
        }

        private WebDriverManager()
        {
            SeleniumConfig seleniumConfig = SeleniumConfig.Load();
            OptionConfig optionConfig = seleniumConfig.Option;

            _webDriver = null;
            foreach (WebDriverConfig webDriverConfig in seleniumConfig.WebDrivers)
            {
                if (webDriverConfig.IsUsed)
                {
                    switch (webDriverConfig.Browser)
                    {
                        case SeleniumConfig.BrowserFirefox:
                            _webDriver = CreateFirefoxDriver(webDriverConfig);
                            break;
                        case SeleniumConfig.BrowserChrome:
                            _webDriver = CreateChromeDriver(webDriverConfig);
                            break;
                        case SeleniumConfig.BrowserIE:
                            _webDriver = CreateInternetExplorerDriver(webDriverConfig);
                            break;
                        default:
                            break;
                    }
                }
            }
            
            _eventFiringWebDriver = new EventFiringWebDriver(_webDriver);
            _eventFiringWebDriver.Manage().Window.Maximize();
            _eventFiringWebDriver.Manage().Timeouts().ImplicitlyWait(
                new TimeSpan(0, 0, optionConfig.ImplicitlyWait));
            _eventFiringWebDriver.Manage().Timeouts().SetPageLoadTimeout(
                new TimeSpan(0, 0, optionConfig.PageLoadTimeout));
        }

        protected IWebDriver CreateChromeDriver(WebDriverConfig webDriverConfig)
        {
            ChromeDriver chromeDriver;
            if (!String.IsNullOrEmpty(webDriverConfig.Path))
            {
                chromeDriver = new ChromeDriver(Path.GetDirectoryName(webDriverConfig.Path));
            }
            else
            {
                chromeDriver = new ChromeDriver();
            }
            return chromeDriver;
        }

        protected IWebDriver CreateFirefoxDriver(WebDriverConfig webDriverConfig)
        {
            FirefoxDriver firefoxDriver;
            if (!String.IsNullOrEmpty(webDriverConfig.Path))
            {
                firefoxDriver = new FirefoxDriver();
            }
            else
            {
                firefoxDriver = new FirefoxDriver();
            }
            return firefoxDriver;
        }

        protected IWebDriver CreateInternetExplorerDriver(WebDriverConfig webDriverConfig)
        {
            InternetExplorerDriver ieDriver;
            if (!String.IsNullOrEmpty(webDriverConfig.Path))
            {
                ieDriver = new InternetExplorerDriver(Path.GetDirectoryName(webDriverConfig.Path));
            }
            else
            {
                ieDriver = new InternetExplorerDriver();
            }
            return ieDriver;
        }

        public IWebDriver WebDriver
        {
            get { return _webDriver; }
        }

        public EventFiringWebDriver EventFiringWebDriver
        {
            get { return _eventFiringWebDriver; }
        }
    }
}
